#include <gtest/gtest.h>
#include <iostream>
#include <string>

#include "containers/os_deque.h"
#include "containers/os_forward_list.h"
#include "containers/os_list.h"
#include "containers/os_map.h"
#include "containers/os_multimap.h"
#include "containers/os_multiset.h"
#include "containers/os_priority_queue.h"
#include "containers/os_queue.h"
#include "containers/os_set.h"
#include "containers/os_stack.h"
#include "containers/os_unordered_map.h"
#include "containers/os_unordered_multimap.h"
#include "containers/os_unordered_multiset.h"
#include "containers/os_unordered_set.h"
#include "containers/os_vector.h"
#include "log/logger.h"

TEST(os_memery_test_container, test_vector)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();        // 总内存
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();      // 当前内存
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();        // 内存分配峰值
    size_t init_remaining = get_memery_manager()->get_remaining_memory();       // 剩余内存
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();      // 内存分配总次数
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();  // 内存释放总次数

    {
        os_vector_init(int, vec);
        vec.reserve(4);
        vec.push_back(1);
        vec.push_back(2);
        EXPECT_EQ(vec[0], 1);
        EXPECT_EQ(vec[1], 2);
        EXPECT_EQ(vec.size(), 2);

        EXPECT_EQ(get_memery_manager()->get_total_memory(), init_total_memory);
        EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc + sizeof(int) * vec.capacity());
        EXPECT_EQ(get_memery_manager()->get_total_allocated(), init_total_alloc + 1);
        EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining - sizeof(int) * vec.capacity());
        EXPECT_EQ(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
        vec.clear();
        EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining - sizeof(int) * vec.capacity());
    }
    EXPECT_EQ(get_memery_manager()->get_total_memory(), init_total_memory);
    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_EQ(get_memery_manager()->get_total_allocated(), init_total_alloc + 1);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining);
    EXPECT_EQ(get_memery_manager()->get_total_deallocated(), init_total_dealloc + 1);
    // 指针vector 测试
    size_t init_total_memory_2 = get_memery_manager()->get_total_memory();        // 总内存
    size_t init_cur_alloc_2 = get_memery_manager()->get_current_allocated();      // 当前内存
    size_t init_peak_alloc_2 = get_memery_manager()->get_peak_allocated();        // 内存分配峰值
    size_t init_remaining_2 = get_memery_manager()->get_remaining_memory();       // 剩余内存
    size_t init_total_alloc_2 = get_memery_manager()->get_total_allocated();      // 内存分配总次数
    size_t init_total_dealloc_2 = get_memery_manager()->get_total_deallocated();  // 内存释放总次数
    auto vec_ptr = os_new_vector(int);
    EXPECT_EQ(get_memery_manager()->get_total_memory(), init_total_memory_2);
    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc_2 + sizeof(os_vector<int>));
    EXPECT_EQ(get_memery_manager()->get_total_allocated(), init_total_alloc_2 + 1);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining_2 - sizeof(os_vector<int>));
    EXPECT_EQ(get_memery_manager()->get_total_deallocated(), init_total_dealloc_2);

    vec_ptr->reserve(4);
    vec_ptr->push_back(1);
    vec_ptr->push_back(2);
    EXPECT_EQ((*vec_ptr)[0], 1);
    EXPECT_EQ((*vec_ptr)[1], 2);
    EXPECT_EQ((*vec_ptr).size(), 2);

    EXPECT_EQ(get_memery_manager()->get_total_memory(), init_total_memory_2);
    EXPECT_EQ(get_memery_manager()->get_current_allocated(),
              init_cur_alloc_2 + sizeof(os_vector<int>) + sizeof(int) * vec_ptr->capacity());
    EXPECT_EQ(get_memery_manager()->get_total_allocated(), init_total_alloc_2 + 1 + 1);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(),
              init_remaining_2 - sizeof(os_vector<int>) - sizeof(int) * vec_ptr->capacity());
    EXPECT_EQ(get_memery_manager()->get_total_deallocated(), init_total_dealloc_2);
    os_delete vec_ptr;
    EXPECT_EQ(get_memery_manager()->get_total_deallocated(), init_total_dealloc_2 + 2);
}

TEST(os_memery_test_container, test_deque)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    size_t old_init_cur_alloc = init_cur_alloc;
    size_t old_init_total_alloc = init_total_alloc;
    size_t old_init_remaining = init_remaining;
    size_t old_init_total_dealloc = init_total_dealloc;
    {
        os_deque_init(int, deq);
        init_total_memory = get_memery_manager()->get_total_memory();
        init_cur_alloc = get_memery_manager()->get_current_allocated();
        init_peak_alloc = get_memery_manager()->get_peak_allocated();
        init_remaining = get_memery_manager()->get_remaining_memory();
        init_total_alloc = get_memery_manager()->get_total_allocated();
        init_total_dealloc = get_memery_manager()->get_total_deallocated();
        deq.push_back(1);
        deq.push_front(2);
        EXPECT_EQ(deq[0], 2);
        EXPECT_EQ(deq[1], 1);
        EXPECT_EQ(deq.size(), 2);
        EXPECT_EQ(get_memery_manager()->get_total_memory(), init_total_memory);
        EXPECT_GT(get_memery_manager()->get_current_allocated(), init_cur_alloc);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);
        EXPECT_EQ(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
        deq.clear();
    }
    EXPECT_EQ(get_memery_manager()->get_total_memory(), init_total_memory);
    EXPECT_EQ(get_memery_manager()->get_current_allocated(), old_init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_allocated(), old_init_total_alloc);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(), old_init_remaining);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), old_init_total_dealloc);
}

TEST(os_memery_test_container, test_forward_list)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_forward_list_init(int, flist);
        size_t list_init_memory = get_memery_manager()->get_current_allocated();
        flist.push_front(1);
        flist.push_front(2);
        flist.push_front(3);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), list_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        flist.clear();
        EXPECT_EQ(get_memery_manager()->get_current_allocated(), list_init_memory);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_list)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_list_init(int, list);
        size_t list_init_memory = get_memery_manager()->get_current_allocated();
        list.push_back(1);
        list.push_back(2);
        list.push_front(3);

        EXPECT_EQ(list.size(), 3);
        EXPECT_EQ(list.front(), 3);
        EXPECT_EQ(list.back(), 2);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), list_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        list.clear();
        EXPECT_EQ(get_memery_manager()->get_current_allocated(), list_init_memory);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_map)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_map_init(int, std::string, map);
        size_t map_init_memory = get_memery_manager()->get_current_allocated();
        map[1] = "one";
        map[2] = "two";
        map[3] = "three";

        EXPECT_EQ(map.size(), 3);
        EXPECT_EQ(map[1], "one");
        EXPECT_EQ(map[2], "two");
        EXPECT_EQ(map[3], "three");

        EXPECT_GT(get_memery_manager()->get_current_allocated(), map_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        map.clear();
        EXPECT_EQ(get_memery_manager()->get_current_allocated(), map_init_memory);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_multimap)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_multimap_init(int, std::string, mmap);
        size_t mmap_init_memory = get_memery_manager()->get_current_allocated();
        mmap.insert({ 1, "one" });
        mmap.insert({ 1, "another one" });
        mmap.insert({ 2, "two" });

        EXPECT_EQ(mmap.size(), 3);

        auto range = mmap.equal_range(1);
        int count = 0;
        for (auto it = range.first; it != range.second; ++it) {
            count++;
        }
        EXPECT_EQ(count, 2);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), mmap_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        mmap.clear();
        EXPECT_EQ(get_memery_manager()->get_current_allocated(), mmap_init_memory);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_multiset)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_multiset_init(int, mset);
        size_t mset_init_memory = get_memery_manager()->get_current_allocated();
        mset.insert(1);
        mset.insert(1);
        mset.insert(2);

        EXPECT_EQ(mset.size(), 3);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), mset_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        mset.clear();
        EXPECT_EQ(get_memery_manager()->get_current_allocated(), mset_init_memory);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_priority_queue)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_priority_queue_init(int, pqueue);
        size_t pqueue_init_memory = get_memery_manager()->get_current_allocated();
        pqueue.push(1);
        pqueue.push(3);
        pqueue.push(2);

        EXPECT_EQ(pqueue.size(), 3);
        EXPECT_EQ(pqueue.top(), 3);  // 最大值应该在顶部
        pqueue.pop();
        EXPECT_EQ(pqueue.top(), 2);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), pqueue_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_queue)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_queue_init(int, queue);
        size_t queue_init_memory = get_memery_manager()->get_current_allocated();
        queue.push(1);
        queue.push(2);
        queue.push(3);

        EXPECT_EQ(queue.size(), 3);
        EXPECT_EQ(queue.front(), 1);
        EXPECT_EQ(queue.back(), 3);

        queue.pop();
        EXPECT_EQ(queue.front(), 2);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), init_cur_alloc);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining);
}

TEST(os_memery_test_container, test_set)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_set_init(int, set);
        size_t set_init_memory = get_memery_manager()->get_current_allocated();
        set.insert(1);
        set.insert(2);
        set.insert(1);  // 重复元素不会插入

        EXPECT_EQ(set.size(), 2);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), set_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        set.clear();
        EXPECT_EQ(get_memery_manager()->get_current_allocated(), set_init_memory);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining);
}

TEST(os_memery_test_container, test_stack)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_stack_init(int, stack);
        size_t stack_init_memory = get_memery_manager()->get_current_allocated();
        stack.push(1);
        stack.push(2);
        stack.push(3);

        EXPECT_EQ(stack.size(), 3);
        EXPECT_EQ(stack.top(), 3);

        stack.pop();
        EXPECT_EQ(stack.top(), 2);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining);
}

TEST(os_memery_test_container, test_unordered_map)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_unordered_map_init(int, std::string, umap);
        size_t umap_init_memory = get_memery_manager()->get_current_allocated();
        umap[1] = "one";
        umap[2] = "two";
        umap[3] = "three";

        EXPECT_EQ(umap.size(), 3);
        EXPECT_EQ(umap[1], "one");
        EXPECT_EQ(umap[2], "two");
        EXPECT_EQ(umap[3], "three");

        EXPECT_GT(get_memery_manager()->get_current_allocated(), umap_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        umap.clear();
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_unordered_multimap)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_unordered_multimap_init(int, std::string, ummap);
        size_t ummap_init_memory = get_memery_manager()->get_current_allocated();
        ummap.insert({ 1, "one" });
        ummap.insert({ 1, "another one" });
        ummap.insert({ 2, "two" });

        EXPECT_EQ(ummap.size(), 3);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), ummap_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        ummap.clear();
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
    EXPECT_EQ(get_memery_manager()->get_remaining_memory(), init_remaining);
}

TEST(os_memery_test_container, test_unordered_multiset)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_unordered_multiset_init(int, umset);
        size_t umset_init_memory = get_memery_manager()->get_current_allocated();
        umset.insert(1);
        umset.insert(1);
        umset.insert(2);

        EXPECT_EQ(umset.size(), 3);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), umset_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        umset.clear();
    }

    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);
}

TEST(os_memery_test_container, test_unordered_set)
{
    size_t init_total_memory = get_memery_manager()->get_total_memory();
    size_t init_cur_alloc = get_memery_manager()->get_current_allocated();
    size_t init_peak_alloc = get_memery_manager()->get_peak_allocated();
    size_t init_remaining = get_memery_manager()->get_remaining_memory();
    size_t init_total_alloc = get_memery_manager()->get_total_allocated();
    size_t init_total_dealloc = get_memery_manager()->get_total_deallocated();

    {
        os_unordered_set_init(int, uset);
        size_t uset_init_memory = get_memery_manager()->get_current_allocated();
        uset.insert(1);
        uset.insert(2);
        uset.insert(1);  // 重复元素不会插入

        EXPECT_EQ(uset.size(), 2);

        EXPECT_GT(get_memery_manager()->get_current_allocated(), uset_init_memory);
        EXPECT_GT(get_memery_manager()->get_total_allocated(), init_total_alloc);
        EXPECT_LT(get_memery_manager()->get_remaining_memory(), init_remaining);

        uset.clear();
    }
    EXPECT_EQ(get_memery_manager()->get_current_allocated(), init_cur_alloc);
    EXPECT_GT(get_memery_manager()->get_total_deallocated(), init_total_dealloc);

    auto uset = os_new_unordered_set(int);
    uset->insert(1);
    uset->insert(2);
    uset->insert(3);
    uset->insert(4);
    uset->insert(5);
    uset->insert(1);
    uset->insert(2);
    uset->insert(3);
    uset->insert(4);
    uset->insert(5);
    uset->insert(1);
    uset->insert(2);

    // os_delete uset;
}

class test_container
{
private:
    int m_data;

public:
    test_container(const test_container& other)
    {
        m_data = other.m_data;
        LOGSI << "test_container::test_container() copy:" << m_data;
    }
    test_container(int arg);
    int data();
    ~test_container();
};

test_container::test_container(int arg) :
    m_data(arg)
{
    LOGSI << "test_container::test_container():" << m_data;
}
int test_container::data()
{
    return m_data;
}
test_container::~test_container()
{
    LOGSI << "test_container::~test_container():" << m_data;
}

TEST(os_memery_test_container, test_class_type)
{
    LOGSI << "test_class_type 1 start";
    {
        os_vector_init(test_container, vec);
        vec.push_back(test_container(1));
    }

    LOGSI << "test_class_type 1 end";
    LOGSI << "test_class_type 2 start";
    {
        os_vector_init(test_container*, vec2);
        vec2.push_back(os_new test_container(2));
        auto ptr = vec2.back();
        os_delete ptr;
        vec2.push_back(ptr);
    }

    LOGSI << "test_class_type 2 end";
    LOGSI << "test_class_type 3 start";
    {
        auto vec3 = os_new_vector(test_container);
        vec3->push_back(test_container(3));
        os_delete vec3;
    }

    LOGSI << "test_class_type 3 end";
    LOGSI << "test_class_type 4 start";
    {
        auto vec4 = os_new_vector(test_container*);
        vec4->push_back(os_new test_container(4));
        os_delete vec4->back();
        os_delete vec4;
    }

    LOGSI << "test_class_type 4 end";
}